package com.wxy.selector;


import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

/**
 * 在非阻塞模式下，不管有没有连接线程都会一直运行，造成大量CPU性能的浪费
 * 解决方法：使用selector
 * @author 47868
 */
public class Server {
    public static void split(ByteBuffer buffer) {
        buffer.flip();
        for(int i=1;i<buffer.limit();i++){
            if((char)buffer.get(i)=='\n'){
                int data = i+1-buffer.position();
                ByteBuffer buffer1 = ByteBuffer.allocate(data);
                for(int j=0;j<data;j++){
                    buffer1.put(buffer.get());
                }
                buffer1.flip();
                while(buffer1.hasRemaining()){
                    System.out.print((char)buffer1.get());
                }
                buffer1.compact();
            }
        }
//        if(buffer.position()<buffer.limit()){
//            while(buffer.hasRemaining()){
//                System.out.print((char)buffer.get());
//            }
//            System.out.println();
//        }
        buffer.compact();
    }
    public static void main(String[] args) throws IOException {
        //1.创建selector
        Selector selector = Selector.open();

        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);
        //建立selector和channel的联系
        SelectionKey sscKey = serverSocketChannel.register(selector, 0,null);
        //绑定事件
        sscKey.interestOps(SelectionKey.OP_ACCEPT);
        //System.out.println("orginal key:" + sscKey);
        serverSocketChannel.bind(new InetSocketAddress(8080));
        while (true) {
            //没有事件发生 线程阻塞   事件要么处理要么使用selectionKey.cancel取消,不能置之不理
            selector.select();
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                //处理key的时候要从selectedKeys集合中删除，否则下次处理会出现问题
                iterator.remove();
                //System.out.println("key : " + key);
                if (key.isAcceptable()) {
                    ServerSocketChannel channel = (ServerSocketChannel) key.channel();
                    SocketChannel sc = channel.accept();
                    sc.configureBlocking(false);
                    //将sc注册到selector中
                    ByteBuffer buffer = ByteBuffer.allocate(20);
                    //添加附件 每个socketChannel独有的
                    SelectionKey sKey = sc.register(selector,0,buffer);
                    sKey.interestOps(SelectionKey.OP_READ);
                    System.out.println(sc);
                } else if (key.isReadable()) {
                    try {
                        SocketChannel channel = (SocketChannel) key.channel();
                        ByteBuffer selfBuffer =(ByteBuffer) key.attachment();
                        int bytesRead = channel.read(selfBuffer);
                        // 处理客户端正常关闭连接的情况
                        if (bytesRead == -1) {
                            //System.out.println("客户端正常断开连接: " + channel);
                            key.cancel(); // 取消Key
                            continue;
                        }
                        split(selfBuffer);
                        if(selfBuffer.position()==selfBuffer.limit()){
                            ByteBuffer newBuffer = ByteBuffer.allocate(selfBuffer.capacity()*2);
                            selfBuffer.flip();
                            newBuffer.put(selfBuffer);
                            key.attach(newBuffer);
                        }
                    } catch (Exception e){
                        System.out.println(e.getMessage());
                        key.cancel();
                    }
                }
            }
        }
    }
}
